﻿/*
 * 作者：新生命开发团队（http://www.newlifex.com/）
 * 
 * 版权：版权所有 (C) 新生命开发团队 2002-2014
*/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using CuteAnt.Serialization;

namespace CuteAnt.Messaging
{
	/// <summary>指定类型的实体对象数组消息</summary>
	/// <remarks>
	/// 有些列表对象不适合直接序列化，并且不方便每次都进行转换，（如XCode的EntityList），此时适合用实体数组消息。
	/// 实体对象个数由<see cref="Values"/>决定，以编码整数来存储。
	/// 不写长度，所以<see cref="Message"/>为空时后面不能有其它包
	/// </remarks>
	public class EntitiesMessage : Message, IAccessor
	{
		/// <summary>消息类型</summary>
		[XmlIgnore]
		public override MessageKind Kind { get { return MessageKind.Entities; } }

		private Type _Type;

		/// <summary>实体类型。可以是接口或抽象类型（要求对象容器能识别）</summary>
		public Type Type
		{
			get
			{
				if (_Type == null && _Values != null && _Values.Count > 0) _Type = _Values[0].GetType();
				return _Type;
			}
			set { _Type = value; }
		}

		private IList _Values;

		/// <summary>实体列表</summary>
		public IList Values
		{
			get { return _Values ?? (_Values = new List<Object>()); }
			set
			{
				_Values = value;
				if (value != null && value.Count > 0)
				{
					foreach (var item in value)
					{
						if (item != null)
						{
							_Type = item.GetType();
							break;
						}
					}
				}
			}
		}

		#region IAccessor 成员

		Boolean IAccessor.Read(IReader reader)
		{
			reader.Depth++;

			Object v = null;
			if (!reader.ReadObject(typeof(Type), ref v, null)) return false;
			Type = v as Type;
			if (Type != null)
			{
				var lt = typeof(List<>).MakeGenericType(Type);

				v = null;
				if (!reader.ReadObject(lt, ref v, null)) return false;
				Values = v as IList;
			}
			reader.Depth--;
			return true;
		}

		Boolean IAccessor.ReadComplete(IReader reader, Boolean success)
		{
			return success;
		}

		Boolean IAccessor.Write(IWriter writer)
		{
			writer.Depth++;
			writer.WriteObject(Type);
			if (Type != null)
			{
				var lt = typeof(List<>).MakeGenericType(Type);
				writer.WriteObject(Values, lt, null);
			}
			writer.Depth--;
			return true;
		}

		Boolean IAccessor.WriteComplete(IWriter writer, Boolean success)
		{
			return success;
		}

		#endregion

		#region 辅助

		/// <summary>已重载。</summary>
		/// <returns></returns>
		public override string ToString()
		{
			var vs = Values;
			if (vs != null)
				return String.Format("{0} Type={1} Count={2}", base.ToString(), Type, vs.Count);
			else
				return base.ToString();
		}

		#endregion
	}
}